node.js express boilerplate
node.js express 프로젝트를 시작할 때 주로 사용되는 패키지들을 정리한 bilerplate
express setup
install
npm install express express-session
npm install --save-dev nodemon
npm install winston winston-daily-rotate-file morgan
npm install cookie-parser
npm install cors
cors
코드
const cors = require("cors");
const corsOptions = require("./config/corsOptions");
const allowedOrigins = require("./allowedOrigins");
const corsOptions = {
origin: (origin, callback) => {
if (allowedOrigins.indexOf(origin) !== -1 || !origin) {
callback(null, true);
} else {
callback(new Error("Not allowed by CORS"));
}
},
credentials: true,
optionsSuccessStatus: 200,
};
module.exports = corsOptions;
cors allow 목록을 별도로 관리
const allowedOrigins = ["http://localhost:3000", "http://localhost:4000"];
module.exports = allowedOrigins;
모든 credentail을 지정할 것 이 아니라면 별도의 미들웨어를 만들어서 헤더에 Acces-Control-Credentials
을 true로 지정해주면된다.
const allowedOrigins = require("../../config/allowedOrigins");
const credentails = (req, res, next) => {
const origin = req.headers.origin;
console.log(origin);
if (allowedOrigins.includes(origin)) {
console.log("allowed");
res.header("Access-Control-Allow-Credentails", true);
}
next();
};
module.exports = credentails;
parser를 위한 패키지
express parser
express#express.json( [options])
express#express.urlencoded( [options])
express내장 json과 urlencode parser
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
cookieParser
cookieParser
cookie 파싱을 위한 패키지
const cookieParser = require("cookie-parser");
app.use(cookieParser(process.env.COOKIE_SECRET));
session
express-session
세션 관리 패키지
const session = require("express-session");
app.use(
session({
secret: process.env.COOKIE_SECRET,
resave: false,
saveUninitialized: false,
store: new RedisStore({
client: redisClient,
}),
//cookie: { secure: true },
})
);
logger
nodejs winston 과 nodejs morgan 을 이용해서 Logging 시스템을 구축했다.
winston은 log를 다루는 패키지이고 morgan은 http 요청에 대한 logging한다.
즉, winston으로 Logger를 만들고 morgan middleware는 요청 log를 logger에 싣는다.
const logger = require("./utils/logger");
const morganMiddleware = require("./utils/middleware/morgan");
const winston = require("winston");
const winstonDaily = require("winston-daily-rotate-file");
// const appRoot = require("app-root-path");
const process = require("process");
const logDir = `${process.cwd()}/logs`;
const { combine, timestamp, printf, label } = winston.format;
const logFormat = printf(({ level, message, label, timestamp }) => {
return `${timestamp} [${label}] ${level}: ${message}`;
});
const logger = winston.createLogger({
format: combine(
label({ label: "express" }),
timestamp({
format: "YYYY-MM-DD HH:mm:ss",
}),
logFormat
),
transports: [
new winstonDaily({
level: "debug",
datePattern: "YYYY-MM-DD",
dirname: logDir,
filename: `%DATE%.log`,
maxFiles: 30,
zippedArchive: true,
}),
new winstonDaily({
level: "error",
datePattern: "YYYY-MM-DD",
dirname: logDir + "/error",
filename: `%DATE%.error.log`,
maxFiles: 30,
zippedArchive: true,
}),
],
exceptionHandlers: [
new winstonDaily({
level: "error",
datePattern: "YYYY-MM-DD",
dirname: logDir,
filename: `%DATE%.log`,
maxFiles: 30,
zippedArchive: true,
}),
],
});
if (process.env.NODE_ENV !== "production") {
logger.add(
new winston.transports.Console({
format: winston.format.combine(
process.env.NODE_ENV === "development"
? winston.format.colorize()
: winston.format.uncolorize(),
winston.format.simple() // `${info.level}: ${info.message} JSON.stringify({ ...rest })` 포맷으로 출력
),
})
);
}
module.exports = logger;
log를 날짜별 파일에 남기기 위해 winston-dailly-rotate-file 패키지를 사용했다.
logging할 때 만든 logger를 사용한다.
const morgan = require("morgan");
const logger = require("../logger");
const format = () => {
const morganFormat =
process.env.NODE_ENV === "production" ? "combined" : "dev";
return morganFormat;
};
const stream = {
write: (message) =>
logger.info(
message.replace(
/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g,
""
)
),
};
const morganMiddleware = morgan(format(), { stream });
module.exports = morganMiddleware;
전체 코드
// import packages
const express = require("express");
const cors = require("cors");
const cookieParser = require("cookie-parser");
const session = require("express-session");
// import config
const corsOptions = require("./config/corsOptions");
const sessionOptions = require("./config/sessionOptions");
// import utils
const logger = require("./utils/logger");
const morganMiddleware = require("./utils/middleware/morgan");
// express setup
const app = express();
app.use(cors(corsOptions));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser("cookie-secret"));
app.use(morganMiddleware);
app.use(session(sessionOptions));
// test route
app.use(require("./routes"));
const PORT = process.env.PORT || 3000;
app.listen(PORT, logger.info(`Server is running on port ${PORT}`));